import type {
  UploadFile,
  UploadFiles,
  UploadRawFile,
  UploadUserFile,
} from 'element-plus'
import type { ConfigOptions, UploadProps } from './useUpload'
import { ElMessage, ElMessageBox } from 'element-plus'
import { FileUtils } from 'fetm-utils'
import { get } from 'lodash-es'
import { ref } from 'vue'
import { createImageViewer } from './ImageViewer'

/**
 * 仅限多文件上传
 */
export function useMultiUpload(props: UploadProps, config: ConfigOptions) {
  const refValue = ref<string[]>([])
  const refResponses = ref<any[]>([])
  const refOriginFiles = ref<Array<{
    name: string
    size: number
  }>>([])
  const refFileList = ref<UploadUserFile[]>([])
  // 编辑的时候回显，传入逗号隔开的url
  function setValues(urls: string) {
    if (urls) {
      refValue.value = urls.split(',')
      refFileList.value = refValue.value.map((item) => {
        return {
          name: FileUtils.getFileName(item),
          url: item,
        }
      })
    }
    else {
      refValue.value = []
      refFileList.value = []
    }
  }
  return {
    refOriginFiles,
    refValue,
    refResponses,
    refFileList,
    setValues,
    uploadProps: {
      fileList: unref(refFileList) as any[],
      ...props,
      // 内部强制重写
      multiple: true,
      onExceed: (files: File[], uploadFiles: UploadUserFile[]) => {
        ElMessage.warning('文件超出最大个数限制')
      },
      beforeUpload: (file: UploadRawFile) => {
        // 多选上传时每个文件都会走一遍这个方法
        const suffix = FileUtils.getSuffix(file.name)
        if (!props.accept?.includes(suffix)) {
          ElMessage.warning(`文件格式不正确，请上传${props.accept}格式的文件`)
          return false
        }
        if (file.size && config.maxSizeByte && file.size > config.maxSizeByte) {
          const gb = config.maxSizeByte / 1024 / 1024 / 1024
          const mb = config.maxSizeByte / 1024 / 1024
          const kb = config.maxSizeByte / 1024
          let tip = `${gb}Gb`
          if (gb < 1)
            tip = `${mb}Mb`

          if (mb < 1)
            tip = `${kb}kb`

          ElMessage.warning(
            `您上传的文件已超出上传最大限制：${tip}，请重新选择文件`,
          )
          return false
        }
        if (config.hooks?.beforeUpload) {
          const flag = config.hooks.beforeUpload(file)
          if (!flag) {
            return false
          }
        }
        refOriginFiles.value.push({
          name: file.name,
          size: file.size,
        })
      },
      onPreview: (file: UploadFile) => {
        if (props.listType == 'picture' || props.listType == 'picture-card') {
          createImageViewer({
            urlList: file.raw ? [file.url!] : [(config.previewPrefix ?? '') + file.url],
            show: true,
            zIndex: 20241212,
          })
          return
        }
        if (!file.raw && !file.url) {
          return
        }
        ElMessageBox.confirm('想要查看需下载该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }).then(() => {
          if (file.raw) {
            FileUtils.downloadFile(file.raw)
            return
          }
          const url = (config.previewPrefix ?? '') + file.url
          window.open(url)
        })
      },
      onRemove: (file: UploadFile, fileList: UploadFiles) => {
        let url: string | undefined
        if (file.raw) {
          url = get(file.response, config.responseMapping?.url ?? 'url')?.[0]
        }
        else {
          url = file.url
        }
        const index = refValue.value.findIndex(item => url?.includes(item))
        const index2 = refOriginFiles.value.findIndex(item => item.name == file.name)
        const index3 = refResponses.value.findIndex(item => get(item, config.responseMapping?.url ?? 'url')?.[0] == url)
        if (index > -1) {
          refValue.value.splice(index, 1)
        }
        if (index2 > -1) {
          refOriginFiles.value.splice(index, 1)
        }
        if (index3 > -1) {
          refResponses.value.splice(index, 1)
        }
      },
      onSuccess: (response: any, file: UploadFile, fileList: UploadFiles) => {
        refResponses.value.push(response)
        if (
          get(response, config.responseMapping?.code ?? 'code')
          === (config.successCode ?? 0)
        ) {
          refValue.value.push(get(response, config.responseMapping?.url ?? 'url')?.[0])
        }
        else {
          ElMessage.error(
            get(response, config.responseMapping?.message ?? 'message')
            ?? '上传失败',
          )
          const index = fileList.findIndex(item => item.uid == file.uid)
          if (index > -1) {
            fileList.splice(index, 1)
          }
        }
        config.hooks?.onSuccess?.(response, file, fileList)
      },
      onChange: (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
        config.hooks?.onChange?.(uploadFile, uploadFiles)
      },
      onError: (
        error: Error,
        uploadFile: UploadFile,
        uploadFiles: UploadFiles,
      ) => {
        ElMessage.error(error.message ?? '上传失败')
        const index = refOriginFiles.value.findIndex(item => item.name == uploadFile.name)
        if (index > -1) {
          refOriginFiles.value.splice(index, 1)
        }
      },
    },
  }
}
